package com.vesystem.vegua.utils.uamUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class CodeUtils {
    private static Logger logger = LoggerFactory.getLogger(CodeUtils.class);

    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
    private static final String VECTOR = "0000000000000000";
    private static final String AESKEY = "1234567890123456";

    /**
     * 根据用户名生成windows server 上用户密码
     *
     * @param username 用户名
     * @return 登录密码
     */
    public static String generateMd5Password(String username) {
        String password = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] results = md5.digest(username.getBytes(StandardCharsets.UTF_8));
            int i;
            StringBuilder buf = new StringBuilder();
            for (byte b : results) {
                i = b;
                if (i < 0) {
                    i += 256;
                }
                if (i < 16) {
                    buf.append("0");
                }
                buf.append(Integer.toHexString(i));
            }
            password = "Ve:" + buf.toString().substring(0, 8).toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            logger.info(e.getMessage(), e);
        }
        return password;
    }

    /**
     * 原文字符串AES加密为HEx十六进制字符串
     *
     * @param payload 原文字符串
     * @return 十六进制字符串
     */
    public static String getHexStringByAes(String payload) {
        return byte2HexStr(encrypt(payload, AESKEY));
    }

    /**
     * 从HEX十六进制字符串AES解密处原文字符串
     *
     * @param hexString 十六进制字符串
     * @return 原文字符串
     */
    public static String getPlaintextFromHex(String hexString) throws GeneralSecurityException {
        return new String(decrypt(hexStr2Bytes(hexString), AESKEY), StandardCharsets.UTF_8);
    }

    /**
     * 加密
     *
     * @param content    原始明文
     * @param encryptKey AES密钥KEY，16位字符串
     * @return 密文字节数组
     */
    private static byte[] encrypt(String content, String encryptKey) {
        byte[] encryptBytes = null;
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            SecretKeySpec skeySpec = new SecretKeySpec(encryptKey.getBytes(StandardCharsets.UTF_8), "AES");
            IvParameterSpec iv = new IvParameterSpec(VECTOR.getBytes());// 使用CBC模式，需要一个向量iv，可增加加密算法的强度
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            encryptBytes = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
        } catch (GeneralSecurityException e) {
            logger.error(e.getMessage(), e);
        }
        return encryptBytes;
    }

    /**
     * 解密
     *
     * @param encryptBytes 密文字节数组
     * @param decryptKey   AES密钥KEY，16位字符串
     * @return 解密后字节数组
     */
    private static byte[] decrypt(byte[] encryptBytes, String decryptKey) throws GeneralSecurityException {
        byte[] decryptBytes;
//        try {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        SecretKeySpec skeySpec = new SecretKeySpec(decryptKey.getBytes(StandardCharsets.UTF_8), "AES");
        IvParameterSpec iv = new IvParameterSpec(VECTOR.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        decryptBytes = cipher.doFinal(encryptBytes);
        return decryptBytes;
    }

    /**
     * 十六进制字符串转byte[]
     *
     * @param hexStr 十六进制字符串
     * @return byte[]
     */
    private static byte[] hexStr2Bytes(String hexStr) {
        String str = "0123456789ABCDEF";
        char[] hexs = hexStr.toUpperCase().toCharArray();
        byte[] bytes = new byte[hexStr.length() / 2];
        int n;
        for (int i = 0; i < bytes.length; i++) {
            n = str.indexOf(hexs[2 * i]) * 16;
            n += str.indexOf(hexs[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        return bytes;
    }

    /**
     * byte[]转十六进制字符串
     *
     * @param bytes byte[]
     * @return 十六进制字符串
     */
    private static String byte2HexStr(byte[] bytes) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (byte value : bytes) {
            stmp = (Integer.toHexString(value & 0XFF));
            if (stmp.length() == 1)
                hs.append("0").append(stmp);
            else
                hs.append(stmp);
        }
        return hs.toString().toUpperCase();
    }

}
